/**
 * 设置存入localStorage数据
 * 存入格式 {value，timestamp}
 **/
export const setStore = function(key:string,param:any):void{
  let timeStamp = new Date().getTime()
  let value = {
      value:param,
      timeStamp:timeStamp
  }
  localStorage.setItem(key,JSON.stringify(value))
}
/**
 * 获取存入localStorage数据
 * @return null 或者 具体值
 **/
export const getStore = function(key:string):any{
  let obj = localStorage.getItem(key)
  if(obj){
    return JSON.parse(obj).value
  }else{
    return null
  }
}
/**
 * 获取存入localStorage时间
 * @return null 或者 毫秒时
 **/
export const getStoreTime = function(key:string):any{
  let obj = localStorage.getItem(key)
  if(obj){
    return JSON.parse(obj).timeStamp
  }else{
    return null
  }
}
/**
 * 数据处理
 * @author echo.
 * @version 1.5.0
 **/

 interface entire {
  [key: string | number | symbol]: any,
}

// base64 解码（对应下面的函数 Base64Escape）
export function Base64Unescape(str: string) {
  return (str + '==='.slice((str.length + 3) % 4))
    .replace(/-/g, '+')
    .replace(/_/g, '/')
}

// base64 编码会出现 + / = 因此替换成其他字符，url安全
export function Base64Escape(str: string) {
  return str.replace(/\+/g, '-')
    .replace(/\//g, '_')
    .replace(/=/g, '')
}

// 判断是否为空
export function isEmpty(val: any) {
  if (!val && val !== 0) return true
  if (val === undefined) return true
  if (val instanceof Date) return false
  if (typeof val === 'object') return Object.keys(val).length === 0
  if (typeof val === 'string') return val == null || val.length === 0
  return false
}

//判断是否为空
export function isNotEmpty(val: any) {
  return !isEmpty(val)
}

//去空格
export function trim(val: string) {
  return val.replace(/(^\s*)|(\s*$)/g, "")
}

//内容替换
export function replaceAll(text: string, repstr: string, newstr: string) {
  return text.replace(new RegExp(repstr, "gm"), newstr);
}

//月，日 格式化 09
export function formatNumberData(n: any) {
  n = n.toString()
  return n[1] ? n : '0' + n
}
//格式化手机号码
export function formatNumber(num: string) {
  return num.length === 11 ? num.replace(/^(\d{3})\d{4}(\d{4})$/, '$1****$2') : num;
}
//金额格式化
export function rmoney(money: string) {
  return parseFloat(money).toFixed(2).toString().split('').reverse().join('').replace(/(\d{3})/g, '$1,').replace(
    /\,$/, '').split('').reverse().join('');
}

//空值过滤器
export function filterForm(form: object) {
  let newobj: entire = {}
  let obj: entire = {}
  newobj = form
  Object.keys(form).forEach(ele => {
    if (isNotEmpty(newobj[ele])) {
      obj[ele] = newobj[ele]
    }
  });
  return obj;
}

//时间工具
export function funcgetOutTime(date: string) { //获取某个时间点到当前时间的差（秒）
  let nowDate = new Date().getTime()
  let endDate = new Date((date.replace(RegExp('-', 'g'), '/'))).getTime()
  return parseInt(String((endDate - nowDate) / 1000))
}
// 获取数据类型
export function getObjType(obj: any) {
  var toString = Object.prototype.toString;
  var map: entire = {
    '[object Boolean]': 'boolean',
    '[object Number]': 'number',
    '[object String]': 'string',
    '[object Function]': 'function',
    '[object Array]': 'array',
    '[object Date]': 'date',
    '[object RegExp]': 'regExp',
    '[object Undefined]': 'undefined',
    '[object Null]': 'null',
    '[object Object]': 'object'
  };
  //#ifdef H5
  if (obj instanceof Element) {
    return 'element';
  }
  //#endif
  return map[toString.call(obj)];
};

/**
* 对象深拷贝
*/
export function deepClone(data: any) {
  let value: entire = {}
  let type = getObjType(data);
  if (type === 'array') {
    if (isEmpty(value)) {
      value = []
    }
    for (var i = 0, len = data.length; i < len; i++) {
      value.push(deepClone(data[i]));
    }
  } else if (type === 'object') {
    if (isEmpty(value)) {
      value = {}
    }
    for (var key in data) {
      value[key] = deepClone(data[key]);
    }
  } else {
    //不再具有下一层次
    return data;
  }
  return value;
}

export function isWeixin() {
  let ua = navigator.userAgent.toLowerCase()
  if (String(ua.match(/MicroMessenger/i)) === "micromessenger") {
    return true
  } else {
    return false
  }
}



// https://www.html.cn/30-seconds-of-code/#isabsoluteurl
// 代码拷贝自30 seconds of code
export const isAbsoluteURL = (str: string) => /^[a-z][a-z0-9+.-]*:/.test(str)
export const truncateString = (str: string, num: number) => str.length > num ? str.slice(0, num > 3 ? num - 3 : num) + '...' : str;
export const isString = (val: any) => typeof val === 'string'
export const isArray = (val: any) => Array.isArray(val)
export const isNumber = (val: any) => typeof val === 'number';
export const isObject = (obj: any) => obj === Object(obj);
export const getType = (v: { constructor: { name: string } } | null | undefined) => v === undefined ? 'undefined' : v === null ? 'null' : v.constructor.name.toLowerCase();
//循环遍历包含异步事件的函数数组，每次异步事件完成后调用 next 。
export const chainAsync = (fns: ((arg0: () => any) => any)[]) => {
  let curr = 0;
  const next = () => fns[curr++](next);
  next();
};

export const runPromisesInSeries = (ps: any[]) => ps.reduce((p: Promise<any>, next: any) => p.then(next), Promise.resolve());

export const isFunction = (val: any) => typeof val === 'function';
export const UUIDGeneratorBrowser = () => {
  return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, c => {
		return (c === 'x' ? (Math.random() * 16) | 0 : Number('r&0x3') | Number('0x8')).toString(16);
	})
}

export const currentURL = () => window.location.href;

// 防抖
export const debounce = (fn: void, ms = 0) => {
  let timeoutId: string | number | NodeJS.Timeout | undefined;
  return function () {
    clearTimeout(timeoutId);
    timeoutId = setTimeout(() => fn, ms);
  };
};

// 节流
export const throttle = (fn: void, wait: number) => {
  let inThrottle: boolean, lastFn: string | number | NodeJS.Timeout | undefined, lastTime: number;
  return function () {
    if (!inThrottle) {
      fn
      lastTime = Date.now()
      inThrottle = true
    } else {
      clearTimeout(lastFn);
      lastFn = setTimeout(function () {
        if (Date.now() - lastTime >= wait) {
          fn
          lastTime = Date.now();
        }
      }, wait - (Date.now() - lastTime));
    }
  };
};
